namespace SmartMathLibrary
{
    /// <summary>
    /// Interface to implement a QuaternionMatrix class.
    /// </summary>
    public interface IQuaternionMatrix
    {
        /// <summary>
        /// Gets the number of columns.
        /// </summary>
        int Columns { get; }

        /// <summary>
        /// Gets the number of rows.
        /// </summary>
        int Rows { get; }

        /// <summary>
        /// Gets the matrix data in form of an array.
        /// </summary>
        Quaternion[,] MatrixData { get; }

        /// <summary>
        /// Determines whether the current matrix is a square matrix.
        /// </summary>
        /// <value>
        /// True if the current matrix is a square matrix otherwise, false. 
        /// </value>
        bool IsSquareMatrix { get; }

        /// <summary>
        /// Determines whether the current matrix is a diagonal matrix.
        /// </summary>
        /// <value>
        /// True if the current matrix is a diagonal matrix otherwise, false.
        /// </value>
        bool IsDiagonalMatrix { get; }

        /// <summary>
        /// Determines whether the current matrix is a column vector.
        /// </summary>
        /// <value>
        /// True if the current matrix is a column vector otherwise, false.
        /// </value>
        bool IsColumnVector { get; }

        /// <summary>
        /// Determines whether the current matrix is a row vector.
        /// </summary>
        /// <value>
        /// True if this instance is row vector otherwise, false.
        /// </value>
        bool IsRowVector { get; }

        /// <summary>
        /// Gets the trace of the matrix.
        /// </summary>
        /// <value>The trace of the matrix.</value>
        Quaternion Trace { get; }

        /// <summary>
        /// Copies the current instance.
        /// </summary>
        /// <returns>A copy of the current instance.</returns>
        QuaternionMatrix Copy();

        /// <summary>
        /// Extracts the real number part and i number part of the matrix.
        /// </summary>
        /// <returns>A complex matrix which includes the real and i number part of the current matrix.</returns>
        ComplexMatrix ExtractRealNumberPartAndIMatrix();

        /// <summary>
        /// Extracts the j number part and k number part of the matrix.
        /// </summary>
        /// <returns>A complex matrix which includes the j and k number part of the current matrix.</returns>
        ComplexMatrix ExtractJAndKMatrix();

        /// <summary>
        /// Inverts the sign of all real number parts in the matrix.
        /// </summary>
        void InvertRealNumberPart();

        /// <summary>
        /// Inverts the sign of all i number parts in the matrix.
        /// </summary>
        void InvertINumberPart();

        /// <summary>
        /// Inverts the sign of all j number parts in the matrix.
        /// </summary>
        void InvertJNumberPart();

        /// <summary>
        /// Inverts the sign of all k number parts in the matrix.
        /// </summary>
        void InvertKNumberPart();

        /// <summary>
        /// Extracts the real number part of the quaternion values into a new matrix.
        /// </summary>
        /// <returns>The real number part of the quaternion values.</returns>
        Matrix ExtractRealNumberPartMatrix();

        /// <summary>
        /// Extracts the i number part of the quaternion values into a new matrix.
        /// </summary>
        /// <returns>The i number part of the quaternion values.</returns>
        Matrix ExtractINumberPartMatrix();

        /// <summary>
        /// Extracts the j number part of the quaternion values into a new matrix.
        /// </summary>
        /// <returns>The j number part of the quaternion values.</returns>
        Matrix ExtractJNumberPartMatrix();

        /// <summary>
        /// Extracts the k number part of the quaternion values into a new matrix.
        /// </summary>
        /// <returns>The k number part of the quaternion values.</returns>
        Matrix ExtractKNumberPartMatrix();

        /// <summary>
        /// Calculates the main diagonal product of the current matrix.
        /// </summary>
        /// <returns>The main diagonal product of the current matrix.</returns>
        Quaternion CalculateMainDiagonalProduct();

        /// <summary>
        /// Gets the number at a position of the matrix.
        /// </summary>
        /// <param name="position">The position of the value.</param>
        /// <returns>The number at the specified position.</returns>
        Quaternion GetValueAtPosition(MatrixPosition position);

        /// <summary>
        /// Gets the value at the specified position of the matrix.
        /// </summary>
        /// <param name="row">The row index where the value should be set.</param>
        /// <param name="column">The column index where the value should be set.</param>
        /// <returns>The value at the specified position.</returns>
        Quaternion GetValueAtPosition(int row, int column);

        /// <summary>
        /// Transposes the current matrix.
        /// </summary>
        /// <returns>The transposed matrix.</returns>
        QuaternionMatrix Transpose();

        /// <summary>
        /// Sets the number at a position of the matrix.
        /// </summary>
        /// <param name="position">The position where the value should be set.</param>
        /// <param name="value">The number of the element.</param>
        void SetValueAtPosition(MatrixPosition position, Quaternion value);

        /// <summary>
        /// Sets the number at a position of the matrix.
        /// </summary>
        /// <param name="row">The row index of the value to set.</param>
        /// <param name="column">The column index of the value to set.</param>
        /// <param name="value">The value to set.</param>
        void SetValueAtPosition(int row, int column, Quaternion value);

        /// <summary>
        /// Compares the current instance of a matrix to another one.
        /// </summary>
        /// <param name="matrix">The matrix to compare.</param>
        /// <returns>True if both matrices are even otherwise, false.</returns>
        bool CompareTo(QuaternionMatrix matrix);
    }
}